package com.ruoyi.school.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.school.domain.PacClass;
import com.ruoyi.school.domain.PacTeacher;
import com.ruoyi.school.domain.Student;
import com.ruoyi.school.domain.dto.ImportStudentInfo;
import com.ruoyi.school.domain.vo.PacClassInfoVo;
import com.ruoyi.school.domain.vo.SchoolHonorVo;
import com.ruoyi.school.enums.UserSexEnum;
import com.ruoyi.school.service.PacClassService;
import com.ruoyi.school.service.PacClassTeacherService;
import com.ruoyi.school.service.PacTeacherService;
import com.ruoyi.school.service.StudentService;
import com.ruoyi.school.mapper.StudentMapper;
import com.ruoyi.school.utils.CommonUtils;
import com.ruoyi.system.domain.vo.StuCityVo;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.PageUtils.startPage;
import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * @author jeremylin
 * @description 针对表【student(学生)】的数据库操作Service实现
 * @createDate 2025-05-24 16:57:35
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
        implements StudentService {

    @Resource
    private PacClassService pacClassService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private StudentMapper baseMapper;

    @Resource
    private PacClassTeacherService pacClassTeacherService;

    @Resource
    private PacTeacherService pacTeacherService;


    /**
     * 模糊查询学生列表
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getAllByName(Student student) {
        IPage<Student> page = new Page<>(1, 10);
        if (StringUtils.isBlank(student.getStuName())) {
            IPage<Student> studentIPage = lambdaQuery().page(page);
            return studentIPage.getRecords();
        }
        List<Student> list = lambdaQuery()
                .like(Student::getStuName, student.getStuName())
                .list();
        return list;
    }

    /**
     * 根据学生id批量查询
     *
     * @param stuIds
     * @return
     */
    @Override
    public List<Student> selectByStuIds(List<Long> stuIds) {
        if (stuIds != null && !stuIds.isEmpty()) {
            return lambdaQuery().in(Student::getId, stuIds).list();
        }
        return Collections.emptyList();
    }

    /**
     * 查找学生信息
     *
     * @param studentParams
     * @return
     */
    @Override
    public List<Student> selectInfo(Student studentParams) {
        List<Student> one = lambdaQuery()
                .likeRight(StringUtils.isNotBlank(studentParams.getStuName()), Student::getStuName, studentParams.getStuName())
                .eq(Objects.nonNull(studentParams.getStuNum()), Student::getStuNum, studentParams.getStuNum())
                .eq(Objects.nonNull(studentParams.getStuFaculties()), Student::getStuFaculties, studentParams.getStuFaculties())
                .eq(Objects.nonNull(studentParams.getStuPhone()), Student::getStuPhone, studentParams.getStuPhone())
                .eq(Objects.nonNull(studentParams.getYearEnrollment()), Student::getYearEnrollment, studentParams.getYearEnrollment())
                .eq(Objects.nonNull(studentParams.getStuClass()), Student::getStuClass, studentParams.getStuClass())
                .in(Objects.nonNull(studentParams.getClassIds()), Student::getClassId, studentParams.getClassIds())
                .list();

        return one;
    }

    /**
     * 根据用户id查询学生信息
     *
     * @param userId
     * @return
     */
    @Override
    public Student selectByUserId(Long userId) {
        if (Objects.nonNull(userId)) {
            return lambdaQuery()
                    .eq(Student::getUserId, userId).one();
        }
        return null;
    }

    /**
     * 获取我的学生列表
     * 1、先查出，绑定的班级列表
     * 2、再根据班级查出所有的学生
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getMyStuList(Student student) {
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        List<PacClassInfoVo> pacClassInfoVos = pacClassTeacherService.selectByTeacher(user);
        if (pacClassInfoVos != null && !pacClassInfoVos.isEmpty()) {
            startPage();
            List<Integer> ids = pacClassInfoVos.stream().map(PacClass::getId).collect(Collectors.toList());
            return lambdaQuery()
                    .likeRight(StringUtils.isNotBlank(student.getStuName()), Student::getStuName, student.getStuName())
                    .eq(Objects.nonNull(student.getStuNum()), Student::getStuNum, student.getStuNum())
                    .eq(Objects.nonNull(student.getStuFaculties()), Student::getStuFaculties, student.getStuFaculties())
                    .eq(Objects.nonNull(student.getStuPhone()), Student::getStuPhone, student.getStuPhone())
                    .eq(Objects.nonNull(student.getYearEnrollment()), Student::getYearEnrollment, student.getYearEnrollment())
                    .eq(Objects.nonNull(student.getStuClass()), Student::getStuClass, student.getStuClass())
                    .in(Student::getClassId, ids)
                    .list();
        }
        return Collections.emptyList();
    }

    /**
     * 毕业生查询
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getGraduatedStudent(Student student) {
        startPage();
        String sql = "((year_enrollment + 4 < YEAR(CURDATE())) OR (year_enrollment + 4 = YEAR(CURDATE()) AND CURDATE() > CONCAT(YEAR(CURDATE()),'-07-31')))";

        List<Student> list = lambdaQuery()
                .likeRight(StringUtils.isNotBlank(student.getStuName()), Student::getStuName, student.getStuName())
                .likeRight(StringUtils.isNotBlank(student.getStuFaculties()), Student::getStuFaculties, student.getStuFaculties())
                .likeRight(StringUtils.isNotBlank(student.getStuPlace()), Student::getStuPlace, student.getStuPlace())
                .eq(Objects.nonNull(student.getStuPhone()), Student::getStuPhone, student.getStuPhone())
                // 毕业条件：
                .apply(sql)
                .list();

        return list;
    }

    /**
     * 查询学生
     *
     * @param student
     * @return
     */
    @Override
    public Student selectOne(Student student) {
        // 判断student是不是每一个属性都为空
        boolean isEmpty = BeanUtils.allFieldsNull(student);
        if (isEmpty) {
            return null;
        }
        Student one = lambdaQuery()
                .likeRight(StringUtils.isNotBlank(student.getStuName()), Student::getStuName, student.getStuName())
                .eq(Objects.nonNull(student.getStuNum()), Student::getStuNum, student.getStuNum())
                .eq(Objects.nonNull(student.getStuFaculties()), Student::getStuFaculties, student.getStuFaculties())
                .eq(Objects.nonNull(student.getStuPhone()), Student::getStuPhone, student.getStuPhone())
                .eq(Objects.nonNull(student.getYearEnrollment()), Student::getYearEnrollment, student.getYearEnrollment())
                .eq(Objects.nonNull(student.getStuClass()), Student::getStuClass, student.getStuClass())
                .eq(Objects.nonNull(student.getId()), Student::getId, student.getId())
                .one();
        if (one != null) {
            Long userId = one.getUserId();
            SysUser sysUser = sysUserService.selectUserById(userId);
            if (sysUser != null) {
                one.setSex(sysUser.getSex());
            }
        }
        return one;
    }

    /**
     * 学生列表
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getList(Student student) {
        List<Student> list = lambdaQuery()
                .likeRight(StringUtils.isNotBlank(student.getStuName()), Student::getStuName, student.getStuName())
                .eq(Objects.nonNull(student.getStuNum()), Student::getStuNum, student.getStuNum())
                .eq(Objects.nonNull(student.getStuFaculties()), Student::getStuFaculties, student.getStuFaculties())
                .eq(Objects.nonNull(student.getStuPlace()), Student::getStuPlace, student.getStuPlace())
                .eq(Objects.nonNull(student.getStuPhone()), Student::getStuPhone, student.getStuPhone())
                .list();

        List<Long> userIds = list.stream().map(Student::getUserId).collect(Collectors.toList());

        List<SysUser> sysUserList = sysUserService.selectUserListByIds(userIds);

        Map<Long, SysUser> userMap = sysUserList.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));

        list.forEach(item -> {
            SysUser sysUser = userMap.get(item.getUserId());
            // 设置性别
            if (sysUser != null) {
                String sex = sysUser.getSex();
                UserSexEnum anEnum = UserSexEnum.getEnum(sex);
                if (anEnum != null) {
                    item.setSex(anEnum.getInfo());
                }
            }

            // 设置辅导员
            PacTeacher academicTeacherInfo = pacTeacherService.getAcademicTeacherInfo(item.getClassId());
            if (academicTeacherInfo != null) {
                item.setCadreName(academicTeacherInfo.getTeacherName());
            }
        });
        return list;
    }

    /**
     * 获取城市数据
     *
     * @return
     */
    @Override
    public List<StuCityVo> getAllCity() {
        List<StuCityVo> list = lambdaQuery()
                .select(Student::getStuCity)
                .groupBy(Student::getStuCity)
                .list()
                .stream()
                .map(item -> {
                    StuCityVo stuCityVo = new StuCityVo();
                    stuCityVo.setCityName(item.getStuCity());
                    Long count = lambdaQuery()
                            .eq(Student::getStuCity, item.getStuCity())
                            .count();
                    stuCityVo.setCount(Math.toIntExact(count));
                    return stuCityVo;
                }).collect(Collectors.toList());
        return list;
    }

    /**
     * @return
     */
    @Override
    public List<SchoolHonorVo> getSchoolHonor(Student student) {
        List<SchoolHonorVo> listVo = baseMapper.getSchoolHonor(student);
        return listVo;
    }

    /**
     * 根据学号 查找学生信息
     *
     * @param stuNum
     * @return
     */
    @Override
    public Student getOneByStuNum(String stuNum) {
        if (StringUtils.isBlank(stuNum)) {
            throw new BaseException("学号不能为空");
        }
        Student student = lambdaQuery()
                .eq(Student::getStuNum, stuNum)
                .one();
        return student;
    }

    /**
     * 根据用户id查询
     *
     * @param userId
     * @return
     */
    @Override
    public Student getByUserId(Long userId) {
        if (userId != null) {
            return lambdaQuery()
                    .eq(Student::getUserId, userId)
                    .one();
        }
        return null;
    }

    /**
     * 根据用户id，删除学生
     *
     * @param userIds
     */
    @Override
    public void deleteStudentByUserIds(Long[] userIds) {
        lambdaUpdate()
                .in(Student::getUserId, userIds)
                .remove();
    }

    /**
     * 获取优秀学生列表
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getExcellentList(Student student) {
        List<Student> list = lambdaQuery()
                .eq(Objects.nonNull(student.getId()), Student::getId, student.getId())
                .eq(Student::getIsGood, "1")
                .list();

        List<Long> userIds = list.stream().map(Student::getUserId).collect(Collectors.toList());

        List<SysUser> sysUsers = sysUserService.selectByIds(userIds);
        list.forEach(item -> {
            SysUser sysUser = sysUsers.stream().filter(user -> user.getUserId().equals(item.getUserId())).findFirst().orElse(null);
            if (sysUser != null) {
                item.setSysUser(sysUser);
            }
        });
        return list;
    }

    /**
     * 查询所有学生数据
     *
     * @return
     */
    @Override
    public List<ImportStudentInfo> selectList() {
        List<Student> list = lambdaQuery().list();
        List<ImportStudentInfo> infoList = new ArrayList<>();
        list.forEach(item -> {
            ImportStudentInfo info = new ImportStudentInfo();
            info.setStuNum(item.getStuNum());
            info.setStuName(item.getStuName());
            info.setBirth(item.getBirth());
            info.setSex(item.getSex());
            info.setNation(item.getNation());
            info.setYearEnrollment(item.getYearEnrollment());
            info.setDomicile(item.getStuPlace());
            info.setPoliticalOutlook(item.getPoliticalOutlook());
            info.setFaculties(item.getStuFaculties());
            info.setMajor(item.getMajor());
            info.setBigTeam(item.getBigTeam());
            info.setStuClass(item.getStuClass());
            info.setSmallTeam(item.getSmallTeam());
            info.setPhone(item.getStuPhone());
            infoList.add(info);
        });
        return infoList;
    }

    @Override
    public long countBypartyMembers() {
        long count = lambdaQuery()
                .eq(Student::getPartyMember, 2)
                .count();
        return count;
    }

    /**
     * 获取所有的学生 但是没有自己
     *
     * @param student
     * @return
     */
    @Override
    public List<Student> getAllByNameNoMe(Student student) {
        IPage<Student> page = new Page<>(1, 10);
        Student student1 = CommonUtils.getStudent();
        if (StringUtils.isBlank(student.getStuName()) && (student.getIds() == null || student.getIds().isEmpty())) {
            LambdaQueryChainWrapper<Student> query = lambdaQuery();
            if (student1 != null) {
                query.ne(Student::getId, student1.getId());
            }
            IPage<Student> studentIPage = query.page(page);
            return studentIPage.getRecords();
        }
        LambdaQueryChainWrapper<Student> queryChainWrapper = lambdaQuery()
                .like(Objects.nonNull(student.getStuName()), Student::getStuName, student.getStuName())
                .in(Objects.nonNull(student.getIds()), Student::getId, student.getIds());
        if (student1 != null) {
            queryChainWrapper.ne(Student::getId, student1.getId());
        }
        List<Student> list = queryChainWrapper.list();
        return list;
    }
}




